package com.xnx.bincker.leader.utils;

import org.springframework.http.MediaType;
import org.springframework.web.HttpMediaTypeNotAcceptableException;
import org.springframework.web.accept.HeaderContentNegotiationStrategy;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.context.request.ServletWebRequest;

import javax.servlet.http.HttpServletRequest;
import java.util.*;

/**
 * Request工具
 */
public class RequestUtils {
    /**
     * 获取当前的Request
     */
    public static Optional<HttpServletRequest> getCurrentRequest(){
        ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.currentRequestAttributes();
        if(requestAttributes == null) return Optional.empty();
        HttpServletRequest request = requestAttributes.getRequest();
        if(request == null) return Optional.empty();
        return Optional.of(request);
    }

    /**
     * @see #getCurrentRequest()
     */
    public static HttpServletRequest currentRequest(){
        return getCurrentRequest().orElseThrow(()->new RuntimeException("获取Request失败"));
    }

    /**
     * 获取基础路径
     */
    public static String basePath(HttpServletRequest request){
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append(request.getScheme()).append("://");
        stringBuilder.append(request.getServerName());
        int port = request.getServerPort();
        if(port != 80 && port != 443)
            stringBuilder.append(":").append(port);
        stringBuilder.append(request.getContextPath());
        return stringBuilder.toString();
    }

    /**
     * @see #basePath(HttpServletRequest)
     */
    public static String basePath(){
        return basePath(currentRequest());
    }

    /**
     * 获取客户IP地址
     */
    public static String getIpAddress(HttpServletRequest request){
        String ip = request.getHeader("x-forwarded-for");
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("HTTP_CLIENT_IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("HTTP_X_FORWARDED_FOR");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }
        return ip;
    }

    /**
     * @see #getIpAddress(HttpServletRequest)
     */
    public static String getIpAddress(){
        return getIpAddress(currentRequest());
    }

    /**
     * 获取请求类型
     */
    public static List<MediaType> getMediaTypes(HttpServletRequest request){
        try {
            return new HeaderContentNegotiationStrategy().resolveMediaTypes(new ServletWebRequest(request));
        } catch (HttpMediaTypeNotAcceptableException e) {
            return Collections.singletonList(MediaType.ALL);
        }
    }
}
